#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
};

function colorLog(color, message) {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function execCommand(command, options = {}) {
  try {
    const result = execSync(command, { 
      stdio: 'inherit', 
      encoding: 'utf8',
      ...options 
    });
    return result;
  } catch (error) {
    throw new Error(`Command failed: ${command}\n${error.message}`);
  }
}

function getFileSize(filePath) {
  try {
    const stats = fs.statSync(filePath);
    return stats.size;
  } catch {
    return 0;
  }
}

function formatBytes(bytes) {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function analyzeBundleSize() {
  colorLog('blue', '📊 分析构建产物大小...');
  
  const distPath = path.join(process.cwd(), 'dist');
  const tauriDistPath = path.join(process.cwd(), 'src-tauri', 'target', 'release');
  
  if (fs.existsSync(distPath)) {
    const files = fs.readdirSync(distPath, { recursive: true });
    let totalSize = 0;
    
    console.log('\n前端构建产物:');
    files.forEach(file => {
      const filePath = path.join(distPath, file);
      if (fs.statSync(filePath).isFile()) {
        const size = getFileSize(filePath);
        totalSize += size;
        console.log(`  ${file}: ${formatBytes(size)}`);
      }
    });
    
    console.log(`\n前端总大小: ${formatBytes(totalSize)}`);
  }
  
  if (fs.existsSync(tauriDistPath)) {
    const bundlePath = path.join(tauriDistPath, 'bundle');
    if (fs.existsSync(bundlePath)) {
      console.log('\n桌面应用构建产物:');
      const bundleTypes = fs.readdirSync(bundlePath);
      
      bundleTypes.forEach(type => {
        const typePath = path.join(bundlePath, type);
        if (fs.statSync(typePath).isDirectory()) {
          const files = fs.readdirSync(typePath);
          files.forEach(file => {
            const filePath = path.join(typePath, file);
            const size = getFileSize(filePath);
            console.log(`  ${type}/${file}: ${formatBytes(size)}`);
          });
        }
      });
    }
  }
}

function optimizeFrontend() {
  colorLog('blue', '🎯 优化前端构建...');
  
  // 清理旧的构建产物
  if (fs.existsSync('dist')) {
    execCommand('rm -rf dist');
  }
  
  // 设置生产环境变量
  process.env.NODE_ENV = 'production';
  process.env.VITE_BUILD_ANALYZE = 'true';
  
  // 构建前端
  execCommand('npm run build');
  
  // 分析构建产物
  try {
    execCommand('npx vite-bundle-analyzer dist');
  } catch (error) {
    colorLog('yellow', '⚠️  Bundle analyzer not available, skipping analysis');
  }
}

function optimizeRust() {
  colorLog('blue', '🦀 优化 Rust 构建...');
  
  const cargoTomlPath = path.join(process.cwd(), 'src-tauri', 'Cargo.toml');
  let cargoContent = fs.readFileSync(cargoTomlPath, 'utf8');
  
  // 检查是否已有优化配置
  if (!cargoContent.includes('[profile.release]')) {
    colorLog('yellow', '📝 添加 Rust 发布优化配置...');
    
    const optimizationConfig = `
[profile.release]
# 启用链接时优化
lto = true
# 优化代码大小
opt-level = "s"
# 减少调试信息
debug = false
# 启用 panic = abort 以减少二进制大小
panic = "abort"
# 减少并行编译单元以提高优化
codegen-units = 1
# 启用所有优化
overflow-checks = false
`;
    
    cargoContent += optimizationConfig;
    fs.writeFileSync(cargoTomlPath, cargoContent);
  }
  
  // 清理旧的构建产物
  execCommand('cargo clean', { cwd: 'src-tauri' });
  
  // 使用优化标志构建
  process.env.RUSTFLAGS = '-C target-cpu=native';
  execCommand('cargo build --release', { cwd: 'src-tauri' });
}

function stripBinaries() {
  colorLog('blue', '🔧 压缩二进制文件...');
  
  const targetDir = path.join(process.cwd(), 'src-tauri', 'target', 'release');
  const binaryPath = path.join(targetDir, process.platform === 'win32' ? 'app.exe' : 'app');
  
  if (fs.existsSync(binaryPath)) {
    const beforeSize = getFileSize(binaryPath);
    
    try {
      if (process.platform !== 'win32') {
        execCommand(`strip ${binaryPath}`);
      }
      
      // 使用 UPX 压缩（如果可用）
      try {
        execCommand(`upx --best ${binaryPath}`);
        const afterSize = getFileSize(binaryPath);
        const reduction = ((beforeSize - afterSize) / beforeSize * 100).toFixed(1);
        colorLog('green', `✅ 二进制文件压缩: ${formatBytes(beforeSize)} → ${formatBytes(afterSize)} (减少 ${reduction}%)`);
      } catch {
        colorLog('yellow', '⚠️  UPX not available, skipping binary compression');
      }
    } catch (error) {
      colorLog('yellow', `⚠️  Binary stripping failed: ${error.message}`);
    }
  }
}

function generateChecksums() {
  colorLog('blue', '🔐 生成校验和...');
  
  const bundlePath = path.join(process.cwd(), 'src-tauri', 'target', 'release', 'bundle');
  
  if (fs.existsSync(bundlePath)) {
    const checksumFile = path.join(bundlePath, 'checksums.txt');
    let checksums = '';
    
    function processDirectory(dir) {
      const items = fs.readdirSync(dir);
      
      items.forEach(item => {
        const itemPath = path.join(dir, item);
        const stat = fs.statSync(itemPath);
        
        if (stat.isDirectory()) {
          processDirectory(itemPath);
        } else if (stat.isFile() && !item.endsWith('.txt')) {
          try {
            const hash = execCommand(`shasum -a 256 "${itemPath}"`, { encoding: 'utf8' });
            checksums += hash;
          } catch (error) {
            colorLog('yellow', `⚠️  Failed to generate checksum for ${item}`);
          }
        }
      });
    }
    
    processDirectory(bundlePath);
    
    if (checksums) {
      fs.writeFileSync(checksumFile, checksums);
      colorLog('green', `✅ 校验和已生成: ${checksumFile}`);
    }
  }
}

function createReleaseNotes() {
  colorLog('blue', '📝 生成发布说明...');
  
  const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
  const version = packageJson.version;
  
  const releaseNotes = `# Release ${version}

## 构建信息
- 构建时间: ${new Date().toISOString()}
- Node.js 版本: ${process.version}
- 平台: ${process.platform}-${process.arch}

## 变更内容
<!-- 请在此处添加变更内容 -->

## 下载
请从 GitHub Releases 页面下载对应平台的安装包。

## 校验和
所有构建产物的 SHA256 校验和可在 \`checksums.txt\` 文件中找到。
`;
  
  fs.writeFileSync('RELEASE_NOTES.md', releaseNotes);
  colorLog('green', '✅ 发布说明已生成: RELEASE_NOTES.md');
}

function cleanupTempFiles() {
  colorLog('blue', '🧹 清理临时文件...');
  
  const tempDirs = [
    'node_modules/.cache',
    'src-tauri/target/debug',
    '.vite',
    'dist/.vite',
  ];
  
  tempDirs.forEach(dir => {
    if (fs.existsSync(dir)) {
      try {
        execCommand(`rm -rf ${dir}`);
        colorLog('green', `✅ 已清理: ${dir}`);
      } catch (error) {
        colorLog('yellow', `⚠️  清理失败: ${dir}`);
      }
    }
  });
}

async function main() {
  const args = process.argv.slice(2);
  const mode = args[0] || 'full';
  
  colorLog('cyan', '🚀 开始构建优化...');
  console.log('');
  
  try {
    switch (mode) {
      case 'frontend':
        optimizeFrontend();
        break;
        
      case 'backend':
        optimizeRust();
        stripBinaries();
        break;
        
      case 'analyze':
        analyzeBundleSize();
        break;
        
      case 'full':
      default:
        optimizeFrontend();
        optimizeRust();
        stripBinaries();
        generateChecksums();
        createReleaseNotes();
        analyzeBundleSize();
        cleanupTempFiles();
        break;
    }
    
    colorLog('green', '\n✅ 构建优化完成！');
  } catch (error) {
    colorLog('red', `\n❌ 构建优化失败: ${error.message}`);
    process.exit(1);
  }
}

// 显示帮助信息
function showHelp() {
  console.log(`
${colors.bright}Tauri 构建优化工具${colors.reset}

${colors.cyan}用法:${colors.reset}
  npm run build:optimize [模式]

${colors.cyan}模式:${colors.reset}
  full        完整优化 (默认)
  frontend    仅优化前端
  backend     仅优化后端
  analyze     分析构建产物大小

${colors.cyan}示例:${colors.reset}
  npm run build:optimize              # 完整优化
  npm run build:optimize frontend     # 仅优化前端
  npm run build:optimize backend      # 仅优化后端
  npm run build:optimize analyze      # 分析构建产物
`);
}

if (require.main === module) {
  if (process.argv.includes('--help') || process.argv.includes('-h')) {
    showHelp();
    process.exit(0);
  }
  
  main().catch((error) => {
    colorLog('red', `❌ 构建优化失败: ${error.message}`);
    process.exit(1);
  });
}

module.exports = {
  optimizeFrontend,
  optimizeRust,
  stripBinaries,
  analyzeBundleSize,
  generateChecksums,
};
